package com.qf.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.constant.AppConstant;
import com.qf.entity.AppInfo;
import com.qf.entity.DevUser;
import com.qf.enums.AppEnum;
import com.qf.enums.AppStatusEnum;
import com.qf.exception.AppException;
import com.qf.mapper.AppInfoMapper;
import com.qf.service.AppInfoService;
import com.qf.util.RedisUtil;
import com.qf.vo.AppMaintainVO;
import com.qf.vo.AppVersionVO;
import com.qf.vo.DownloadsVO;
import com.qf.vo.TableListVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.SerializationUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class AppInfoServiceImpl implements AppInfoService {

    @Resource
    private AppInfoMapper appInfoMapper;
    @Autowired
    private RedisUtil redisUtil;

    private final String SESSION_DOWNLOADS = "shiro-session:downloads";

    private final int SESSION_TIME_OUT = 600;


    @Override
    public List<DownloadsVO> findOrderByDownloads() {

        List<DownloadsVO> downloadsVOList =null;
        //查询redis中是否有软件下载量信息
        byte[] key = SerializationUtils.serialize(SESSION_DOWNLOADS);
        byte[] value = redisUtil.get(key);
        if (value!=null){
            downloadsVOList = (List<DownloadsVO>) SerializationUtils.deserialize(value);
            System.out.println("从redis中获得下载量信息");
        }else {
            List<AppInfo> list = appInfoMapper.findOrderByDownloads(AppConstant.DOWNLOADS);

            downloadsVOList = new ArrayList<>();

            for (AppInfo appInfo : list) {
                downloadsVOList.add(new DownloadsVO(appInfo.getSoftwareName(),appInfo.getDownloads()));
            }
            //将查到的数据放入redis中
            if (list!=null&&list.size()!=0){
                byte[] listValue = SerializationUtils.serialize(downloadsVOList);
                redisUtil.setAndExpire(key,listValue,SESSION_TIME_OUT);
                System.out.println("在数据库中查询下载量信息并放入redis中");
            }
        }


        return downloadsVOList;
    }

    @Override
    public TableListVO<AppMaintainVO> findPage(HashMap<String, Object> map) {

        PageHelper.startPage((int) map.get("page"),(int) map.get("limit"));

        List<AppMaintainVO> list = appInfoMapper.findPage(map);

        PageInfo<AppMaintainVO> pageInfo = new PageInfo<>(list);

        TableListVO vo = new TableListVO();
        vo.setCount(pageInfo.getTotal());
        vo.setData(pageInfo.getList());


        return vo;
    }

    @Override
    @Transactional
    public void addAppInfo(AppInfo appInfo) {
        //封装参数  待审核、下载次数为0、 添加人id
        appInfo.setAppStatus(AppStatusEnum.WAIT_EXAMINE.getStatus());
        Long devUserId = ((DevUser)SecurityUtils.getSubject().getPrincipal()).getId();
        appInfo.setDevId(devUserId);
        appInfo.setDownloads(AppConstant.DOWNLOAD);

        int count = appInfoMapper.insertSelective(appInfo);
        if (count!=1){
            log.error("【添加APP信息】 添加APP信息失败！ appInfo={}",appInfo);
            throw  new AppException(AppEnum.APPINFO_ADD_ERROR);
        }
    }

    @Override
    @Transactional
    public void updateAppStatusUPByIds(List<Long> ids) {

        Example example = new Example(AppInfo.class);
        Example.Criteria c = example.createCriteria();
        c.andIn("id",ids);

        List<AppInfo> appInfoList = appInfoMapper.selectByExample(example);

        for (AppInfo appInfo : appInfoList) {
            if (appInfo.getAppStatus()==AppStatusEnum.WAIT_EXAMINE.getStatus()||
                appInfo.getAppStatus()==AppStatusEnum.EXAMINE_NOT.getStatus()||
                appInfo.getAppStatus()==AppStatusEnum.ON.getStatus()){
                log.info("【App上架】APP状态为{}无法进行上架操作！ appinfo={}",appInfo.getAppStatus(),appInfo);
                throw new AppException(AppEnum.PARAM_ERROR);
            }
        }

        AppInfo appInfo = new AppInfo();
        appInfo.setOnSaleDate(new Date());
        appInfo.setAppStatus(AppStatusEnum.ON.getStatus());
        int count = appInfoMapper.updateByExampleSelective(appInfo, example);

        if (count != ids.size()){
            log.error("【APP上架】 APP上架操作失败！appInfo={},example={},count={}",appInfo,example,count);
            throw new AppException(AppEnum.UP_APPINFO_ERROR);
        }

    }

    @Override
    @Transactional
    public void updateAppStatusDOWNByIds(List<Long> ids) {
        Example example = new Example(AppInfo.class);
        Example.Criteria c = example.createCriteria();
        c.andIn("id",ids);

        List<AppInfo> appInfoList = appInfoMapper.selectByExample(example);

        for (AppInfo appInfo : appInfoList) {
            if (appInfo.getAppStatus() != AppStatusEnum.ON.getStatus()){
                log.info("【App上架】APP状态为{}无法进行下架操作！ appinfo={}",appInfo.getAppStatus(),appInfo);
                throw new AppException(AppEnum.PARAM_ERROR);
            }
        }


        AppInfo appInfo = new AppInfo();
        appInfo.setOffSaleDate(new Date());
        appInfo.setAppStatus(AppStatusEnum.OFF.getStatus());
        int count = appInfoMapper.updateByExampleSelective(appInfo, example);

        if (count != ids.size()){
            log.error("【APP下架】 APP下架操作失败！appInfo={},example={},count={}",appInfo,example,count);
            throw new AppException(AppEnum.UP_APPINFO_ERROR);
        }


    }

    @Override
    @Transactional
    public void deleteByIds(List<Long> ids) {

        Example example = new Example(AppInfo.class);
        Example.Criteria c = example.createCriteria();
        c.andIn("id",ids);

        int count = appInfoMapper.deleteByExample(example);

        if (count != ids.size()){
            log.error("【删除APP】删除APP失败！ids={},count={}",ids,count);
            throw new AppException(AppEnum.DELEVE_APPINFO_ERROR);
        }

    }

    @Override
    public AppInfo findAppInfoById(Long appId) {
        return appInfoMapper.selectByPrimaryKey(appId);
    }

    @Override
    @Transactional
    public void updateVersionById(AppInfo newAppInfo) {
        int count = appInfoMapper.updateByPrimaryKeySelective(newAppInfo);
        if (count!=1){
            log.error("【添加APP的版本】 修改app的版本号失败! AppInfo={}",newAppInfo);
            throw new AppException(AppEnum.APPIFNO_UPDATE_VERSIONID_ERROR);
        }
    }

    @Override
    public void updateAppInfo(AppInfo appInfo) {
        int count = appInfoMapper.updateByPrimaryKeySelective(appInfo);
        if (count!=1){
            log.error("【修改APP的信息】 修改app的信息失败! AppInfo={}",appInfo);
            throw new AppException(AppEnum.APPIFNO_UPDATE_ERROR);
        }
    }


}
